/**
 * Copyright (C) 2021 - 2031 O-Cubes Co., Ltd.
 */

/****************************************************************
 *  @file    drv.c
 *  @brief   Drivers source file
 *  @version v1.0
 *  @date    03. Apr. 2023
 *  @author  liuchao
 ****************************************************************/

#include <stdint.h>

#include "error.h"
#include "drv.h"
#include "autoconf.h"

#ifdef CONFIG_SDK_GPIO
static DEV_GPIO_INT_CFG g_def_gpio_int_cfg =
{
	.int_bit_mask = GPIO_BITS_MASK_ALL, .int_bit_type = GPIO_INT_EDGE_TRIG_ALL,
	.int_bit_polarity = GPIO_INT_ACTIVE_LOW_ALL, .int_bit_debounce = GPIO_INT_NO_DEBOUNCE_ALL
};
#endif

#ifdef CONFIG_SDK_SPICTRL
static DW_SPI_CFG g_spi0_cfg =
{
	.spi_devid = DW_SPI_0_ID, .spi_speed = 1000000, .spi_clk = SPI_CLK_MODE_DEFAULT
};

static DW_SPI_CFG g_spi1_cfg =
{
	.spi_devid = DW_SPI_1_ID, .spi_speed = 1000000, .spi_clk = SPI_CLK_MODE_DEFAULT
};


static DW_SPI_CFG g_spi3_cfg =
{
	.spi_devid = DW_SPI_3_ID, .spi_speed = 25000000, .spi_clk = SPI_CLK_MODE_DEFAULT
};

#endif

#ifdef CONFIG_SDK_I2C
static DW_I2C_CFG g_i2c0_cfg =
{
	.i2c_devid = DW_I2C_0_ID, .i2c_speed_mode = I2C_SPEED_STANDARD,
	.i2c_mode = DEV_MASTER_MODE, .tar_addr = 0x70,
	.i2c_addr_mod = I2C_7BIT_ADDRESS
};

static DW_I2C_CFG g_i2c1_cfg =
{
	.i2c_devid = DW_I2C_1_ID, .i2c_speed_mode = I2C_SPEED_STANDARD,
	.i2c_mode = DEV_MASTER_MODE, .tar_addr = 0x50,
	.i2c_addr_mod = I2C_7BIT_ADDRESS
};
#endif

#ifdef CONFIG_SDK_CRG
static inline void Drv_Crg_Init(void)
{
	pll_init();
}
#endif

#ifdef CONFIG_SDK_PCL
static inline void Drv_Pcl_Init(void)
{
	pcl_init();
}
#endif

#ifdef CONFIG_SDK_GPIO
static int32_t Drv_Gpio_Init(enum gpio_port_obj_t port)
{
	int32_t ercd = E_OK;
	uint32_t dir_bitmask = { 0 };

	DEV_GPIO_PTR gpio_ptr = gpio_get_dev(eGPIO_DEV_OBJ_0, port);
	DRV_CHECK_EXP(gpio_ptr != NULL, E_OBJ);

	ercd = gpio_ptr->gpio_open(dir_bitmask);
	DRV_CHECK_EXP(ercd == E_OK, ercd);
	
	//only port A support int
	if (port == eGPIO_PORT_OBJ_A) {
		ercd = gpio_ptr->gpio_control(GPIO_CMD_SET_BIT_INT_CFG, CONV2VOID(&g_def_gpio_int_cfg));
		DRV_CHECK_EXP(ercd == E_OK, ercd);
	}

error_exit:
	return ercd;
}
#endif

#ifdef CONFIG_SDK_UART
static int32_t Drv_Uart_Init(int uart, uint32_t baud)
{
	int32_t ercd = E_OK;

	DEV_UART_PTR uart_ptr = uart_get_dev(uart);

	DRV_CHECK_EXP(uart_ptr != NULL, E_OBJ);

	ercd = uart_ptr->uart_open(baud);

	DRV_CHECK_EXP(ercd == E_OK, ercd);

error_exit:
	return ercd;
}
#endif

#ifdef CONFIG_SDK_SYSCNT
static inline void Drv_Syscnt_Init(void)
{
	syscnt_init();
}
#endif

#ifdef CONFIG_SDK_TIMER
static int32_t Drv_Timer_Init(int timer)
{
	int32_t ercd = E_OK;

	DEV_TIMER_PTR timer_ptr = timer_get_dev(timer);

	DRV_CHECK_EXP(timer_ptr != NULL, E_OBJ);

	ercd = timer_ptr->timer_open();

	DRV_CHECK_EXP(ercd == E_OK, ercd);

error_exit:
	return ercd;
}
#endif

#ifdef CONFIG_SDK_RTC
static void Drv_Rtc_Init(void)
{
	rtc_init();
}
#endif

#ifdef CONFIG_SDK_PWM
static int32_t Drv_Pwm_Init(enum pwm id)
{
	int32_t ercd = E_OK;
	uint8_t timer_id = 0;
	DEV_TIMER_PTR timer_ptr = NULL;

	if (id == PWM_0) {
		timer_id = DW_TIMER_6_ID;
	} else if (id == PWM_1) {
		timer_id = DW_TIMER_7_ID;
	} else {
		return E_PAR;
	}

	timer_ptr = timer_get_dev(timer_id);

	DRV_CHECK_EXP(timer_ptr != NULL, E_OBJ);

	ercd = timer_ptr->timer_open();

	DRV_CHECK_EXP(ercd == E_OK, ercd);

error_exit:
	return ercd;
}
#endif

#ifdef CONFIG_SDK_QSPIFLASH
static inline int32_t Drv_Flash_Init(void)
{
	return sfud_init();
}
#endif

#ifdef CONFIG_SDK_SPICTRL
static int32_t Drv_Spi_Init(DW_SPI_CFG *spi_cfg)
{
	int32_t ercd = E_OK;
	DEV_SPI_PTR spi_ptr = spi_get_dev(spi_cfg->spi_devid);

	DRV_CHECK_EXP(spi_ptr != NULL, E_OBJ);

	ercd = spi_ptr->spi_open(DEV_MASTER_MODE, spi_cfg->spi_speed);

	DRV_CHECK_EXP(ercd == E_OK, ercd);
#ifndef SPIFLASH_XIP_EN
	ercd = spi_ptr->spi_control(SPI_CMD_SET_CLK_MODE, CONV2VOID(spi_cfg->spi_clk));

	DRV_CHECK_EXP(ercd == E_OK, ercd);
#endif
error_exit:
	return ercd;
}
#endif

#ifdef CONFIG_SDK_I2C
static int32_t Drv_I2c_Init(DW_I2C_CFG *i2c_cfg)
{
	int32_t ercd = E_OK;
	DEV_I2C_PTR i2c_ptr = i2c_get_dev(i2c_cfg->i2c_devid);

	DRV_CHECK_EXP(i2c_ptr != NULL, E_OBJ);

	ercd = i2c_ptr->i2c_open(i2c_cfg->i2c_mode, i2c_cfg->i2c_speed_mode);

	DRV_CHECK_EXP(ercd == E_OK, ercd);

	ercd = i2c_ptr->i2c_control(I2C_CMD_SET_ADDR_MODE, CONV2VOID(i2c_cfg->i2c_addr_mod));

	DRV_CHECK_EXP(ercd == E_OK, ercd);

	ercd = i2c_ptr->i2c_control(I2C_CMD_MST_SET_TAR_ADDR, CONV2VOID(i2c_cfg->tar_addr));

	DRV_CHECK_EXP(ercd == E_OK, ercd);

error_exit:
	return ercd;
}
#endif

#ifdef CONFIG_SDK_WDT
static void wdt_init_isr(void *ptr)
{
	printf("enter wdt0 warning interrupt\r\n");
}

static void Drv_Wdt_Init(enum wdt_port wdt)
{
	uint32_t irq_id = WDT0_IRQn + wdt;
	
	wdt_switch(wdt);
	wdt_init();
	wdt_register_callback(wdt_init_isr);
	irq_attach(irq_id, wdt_isr, CONV2VOID(wdt));
	irq_id = readl(0x10112014UL);
	irq_enable(irq_id);
}

static void Drv_Wdt_Stop(enum wdt_port wdt)
{
	wdt_switch(wdt);
	wdt_stop();
}

#endif

#ifdef CONFIG_SDK_DMA
static inline void Drv_Dma_Init(void)
{
	dma_init();
}
#endif

#ifdef CONFIG_SDK_SARADC
static void Drv_Saradc_Init(void)
{
	saradc_default_init();
}
#endif
//saradc enable bit in sdadc reg, so saradc must init before sdadc
#ifdef CONFIG_SDK_SDADC
static void Drv_Sdadc_Init(void)
{
	sdadc_init();
}
#endif

#ifdef CONFIG_SDK_MONITOR
static void Drv_Monitor_Init(void)
{
	monitor_init();
}
#endif

void Drv_Init(void)
{
	uint32_t i = 0;

#ifdef CONFIG_SDK_SYSCNT
	Drv_Syscnt_Init();
#endif
#ifdef CONFIG_SDK_CRG
	Drv_Crg_Init();
#endif
#if CONFIG_SDK_WDT
	for (i = eDW_WDT_0; i < eDW_WDT_MAX; i++) {
		Drv_Wdt_Init(i);
	}
#else
    printf("turn off wdg\n");
	Drv_Wdt_Stop(eDW_WDT_0);
	Drv_Wdt_Stop(eDW_WDT_1);
#endif
#ifdef CONFIG_SDK_PCL
	Drv_Pcl_Init();
#endif
#ifdef CONFIG_SDK_UART
	Drv_Uart_Init(DW_UART_0_ID, 115200);
	Drv_Uart_Init(DW_UART_1_ID, 115200);
	Drv_Uart_Init(DW_UART_2_ID, 115200);
	Drv_Uart_Init(DW_UART_3_ID, 115200);
	Drv_Uart_Init(DW_UART_4_ID, 115200);
#endif

#ifdef CONFIG_SDK_RTC
	Drv_Rtc_Init();
#endif

#ifdef CONFIG_SDK_TIMER
	for (i = DW_TIMER_0_ID; i <= DW_TIMER_5_ID; i++) {
		Drv_Timer_Init(i);
	}
#endif

#ifdef CONFIG_SDK_DMA
	Drv_Dma_Init();
#endif

#ifdef CONFIG_SDK_GPIO
	for (i = eGPIO_PORT_OBJ_A; i < eGPIO_PORT_MAX; i++) {
		Drv_Gpio_Init(i);
	}
#endif

#ifdef CONFIG_SDK_PWM
	for (i = PWM_0; i <= PWM_1; i++) {
		Drv_Pwm_Init(i);
	}
#endif

#ifdef CONFIG_SDK_SPICTRL
	Drv_Spi_Init(&g_spi0_cfg);
	Drv_Spi_Init(&g_spi1_cfg);
	Drv_Spi_Init(&g_spi3_cfg);
#endif

#ifdef CONFIG_SDK_QSPIFLASH
	Drv_Flash_Init();
#endif

#ifdef CONFIG_SDK_I2C
	Drv_I2c_Init(&g_i2c0_cfg);
	Drv_I2c_Init(&g_i2c1_cfg);
#endif

#ifdef CONFIG_SDK_SDADC
	Drv_Sdadc_Init();
#endif

#ifdef CONFIG_SDK_SARADC
	Drv_Saradc_Init();
#endif

#ifdef CONFIG_SDK_MONITOR
	Drv_Monitor_Init();
#endif

#ifdef CONFIG_SDK_PMU
	pmu_init();
#endif
//#endif
}

